///usr/share/java/RXTXcomm.jar

import java.util.concurrent.*
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class SimpleRead{
    /** */
    def pool = Executors.newFixedThreadPool(1000)
    
    def runner={sin,data->
            println "Hello read"    
            byte[] buffer = new byte[1024];
            int len = -1;
            try{
                while ( ( len = sin.read(buffer)) > -1 ){
                    data(new String(buffer,0,len));
                }
            }
            catch ( IOException e ){
                e.printStackTrace();
            }            
    }

    def runnerIn={sin,data->
            String ln;
            try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(sin));
                while ((ln = reader.readLine()) !=null ){
                    data(ln);
                }
            }
            catch ( IOException e ){
                e.printStackTrace();
            }            
    }
    
    def runnerOut={sout->
            println "Hello write"    
            def o
            System.in.eachLine() { line ->  
              o=line.replaceAll( "\n", "\r" )+"\r"
              
              sout.print(o)
            }
    }
    
    def runnertest={o->
        while (true){
            sleep(1000)
            println "---$o"
        }
    } as Runnable
    
    void connect ( String portName,speed, Closure data ) throws Exception{
        println "init serial $portName $speed"
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
        if ( portIdentifier.isCurrentlyOwned() ){
            System.out.println("Error: Port is currently in use");
        }
        else{
            CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);
            
            if ( commPort instanceof SerialPort ){

                SerialPort serialPort = (SerialPort) commPort;
                serialPort.setSerialPortParams(speed,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
                
                InputStream sin= serialPort.getInputStream();
                OutputStream sout = serialPort.getOutputStream();
                
                pool.submit({
                    byte[] buffer = new byte[1024];
                    int len = -1;
                    try{
                        while ( ( len = sin.read(buffer)) > -1 ){
                            data(new String(buffer,0,len));
                        }
                    }
                    catch ( IOException e ){
                        e.printStackTrace();
                    }            
                })
                pool.submit({
                    def o
                    
                    
                    System.in.eachLine() { line ->  
                      o=line.replaceAll( "\n", "\r\n" )+"\r\n"
                      sout.write(o.getBytes())
                    }
                })
                
//                Thread.start(runnertest("out"))
//                Thread.start(runnertest("in"))
//                Thread.start(runnerOut(out))
//                Thread.start(runner(sin,data))
println "init done"
                pool.awaitTermination(-1,TimeUnit.SECONDS)

            }
            else{
                System.out.println("Error: Only serial ports are handled by this example.");
            }
        }     
    }
    

    
    public static void main ( String[] args )
    {
        try
        {
            println "available bauds: 115200, 57600, 38400, 31250, 28800, 19200"
            def comm=(args.size()>1)?args[0]:"/dev/ttyUSB0"
            def speed=(args.size()>1)?args[1]:(args.size()==1)?args[0]:57600
            (new SimpleRead()).connect(comm,speed as int, {data->System.out.print(data)});
        }
        catch ( Exception e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}





